import re

from django.contrib.auth.hashers import make_password, check_password

import ending_framework_api.settings.dev
from registered.models import *
from rest_framework import serializers
from django.contrib.auth import authenticate
from django.db.models import Q
from rest_framework.exceptions import APIException, ValidationError
from django.core.cache import cache
from rest_framework_jwt.settings import api_settings
from .models import *

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


#########################登录##################################

class UserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(required=False)
    password = serializers.CharField(required=False)
    number = [3]

    class Meta:
        model = User
        fields = ['username', 'password']

    def _get_token(self, user):
        try:
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return token
        except Exception as e:
            raise ValidationError(e)

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        print(username, password)
        # user = authenticate(username=username, password=password)
        user = User.objects.all().get(username=username)
        print(user)
        if user and not check_password(password,user.password):
            if self.number[0] > 0:
                print('111>>>>>>>>>>>>>>>>')
                output = f'用户名或者密码错误，你还有{self.number[0]}次机会'
                print(self.number[0])
                self.number[0] -= 1
                raise APIException(output)
            else:
                print('222222222222>>>>>>>>>>>>>>')
                User.objects.all().filter(username=username).update(is_active=0)
                raise APIException('你已经输错三次密码，请等待管理员激活！')
        user_active = User.objects.all().filter(username=username, is_active=1).first()
        gender = user.doctor.gender
        mobile = user.doctor.mobile
        print(gender)
        if user_active:
            token = self._get_token(user)
            user_info = {'username': user.username,
                         'id': user.id,
                         'name': user.doctor.name,
                         'user_type': user.user_type,
                         'icon': 'http://127.0.0.1:8000/media/' + str(user.icon)}
            self.context['user'] = user_info
            self.context['user_id'] = user.id
            self.context['name'] = user.doctor.name
            self.context['gender'] = gender
            self.context['mobile'] = mobile
            self.context['user_type'] = user.get_user_type_display()
            self.context['token'] = token
            self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user.icon)
            return attrs
        else:
            raise APIException('等待激活')

#########################登录###################################


###########################注册###############################
class UserMethodsSerializer(serializers.ModelSerializer):
    # 校验密码
    # 第一种管理员情况的校验两次密码是否一样:
    def _get_password(self, attrs):
        print('第三步')
        password = attrs.get('password')
        check_pwd = attrs.get('check_pwd')
        if not password == check_pwd:
            raise APIException('两次密码不一致')
        return True

    def _get_mobile(self, attrs):
        mobile = attrs.get('doctor')['mobile']
        if re.match(r'^1[3-9][0-9]{9}$', str(mobile)):
            return attrs
        else:
            raise APIException('手机号不规范')

    # 全局钩子
    # 第一种管理员情况如果校验密码通过，返回True,把二次校验密码去掉，把username加入上下文管理，
    # 第二种情况是医生或者药管师，因为有一个手机号码需要校验，如果不是医生或者药管师，也就是没有获取doctor字段，就直接返回attrs，保存入库
    def validate(self, attrs):
        if self._get_password(attrs):
            attrs.pop('check_pwd')
        self.context['username'] = attrs.get('username')
        if not attrs.get('doctor'):
            return attrs
        self._get_mobile(attrs)
        return attrs

    def create(self, validated_data):
        print(validated_data)
        # 把刚刚注册的用户都设置初始状态为0，加入字段存进数据库
        validated_data['is_active'] = 0
        # 通过user_type判断是否为管理员，如果是管理员，
        if validated_data.get('user_type') == 1:
            # 把管理员注册的用户名和密码create到Username表中
            user = User.objects.create_user(**validated_data)
            return {'user_id': user.id,
                    'username': user.username,
                    'user_type': user.user_type,
                    'user_state': user.is_active}
        # 如果是医生，先要把医生pop出来，因为是先Crete医生表的字段
        doctor = validated_data.pop('doctor')
        print('第一个医生对象', doctor)
        # 实例化出一个医生对象
        doctor = Doctor.objects.create(**doctor)
        print('第二个医生对象', doctor)
        # User表中的doctor_id存入的是doctor对象？
        validated_data['doctor'] = doctor
        user = User.objects.create_user(**validated_data)

        return {'user_id': user.id,
                'username': user.username,
                'user_type': user.user_type,
                'name': user.doctor.name,
                'mobile': user.doctor.mobile,
                'department': user.doctor.department,
                'user_state': user.is_active}


class DoctorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Doctor
        fields = '__all__'


class UserRegisterSerializer(UserMethodsSerializer):
    doctor = DoctorSerializer()
    # print(doctor)
    check_pwd = serializers.CharField()

    class Meta:
        model = User
        # 只写
        fields = ['username', 'password', 'check_pwd', 'user_type', 'doctor']


class AdminRegisterSerializer(UserMethodsSerializer):
    check_pwd = serializers.CharField()

    # 第一种管理员情况走的序列化类
    # user_type为1的时候，是管理员类型
    class Meta:
        model = User
        fields = ['username', 'password', 'check_pwd', 'user_type']


###########################注册###############################


############################找回密码#############################

class UserForgetSerializer(serializers.ModelSerializer):
    # 这里的code是用户自己输的
    code = serializers.CharField()
    name = serializers.CharField()
    username = serializers.CharField()
    mobile = serializers.CharField()

    class Meta:
        model = User
        fields = ['username', 'name', 'mobile', 'code']

    def validate(self, attrs):
        username = attrs.get('username')
        name = attrs.get('name')
        mobile = attrs.get('mobile')
        code = attrs.get('code')
        print('attrs', username, name, code, mobile)
        user = User.objects.get(username=username, doctor__name=name, doctor__mobile=mobile)
        # print(username,'>>>>>>')
        # user = User.objects.all().filter(username=username).first()
        print(user,'>>11111>>>')
        # user = User.objects.all().filter(username='zxq').first()
        # user = User.objects.get(doctor__name=name)
        if not user:
            raise APIException('未查到该用户')
        old_code = cache.get('set_code_%s' % mobile)
        print(old_code)
        # old_code = '13140'
        # print(old_code)
        print(code)
        if code == old_code:
            print(1)
            cache.set('set_code_%s' % mobile, '')
            self.context['user'] = user.username
            return attrs
        else:
            raise APIException('验证码不正确')


############################## 药品管理表  ####################

# class MedicinesView(serializers.ModelSerializer):
#     class Meta:
#         model = Medicine
#
#         fields = ['id', 'name', 'med_number', 'category', 'total', 'is_ground', 'price', 'department',
#               'department_name', 'is_ground_name', 'ground_num', 'department_code']




# 对药品管理表序列化类
class MedicineSerializer(serializers.ModelSerializer):
    class Meta:
        model = Medicine
        fields = ['id', 'name', 'category']
    # class Meta:
    #     model = Medicine
    #     # 添加要序列化的字段
    #     fields = ['id', 'name', 'med_number', 'category', 'total', 'is_ground', 'price', 'department',
    #               'department_name', 'is_ground_name', 'ground_num', 'ground_num_shu','depart_type_name']
    #     extra_kwargs = {
    #         'department': {'read_only': True},
    #         'department_name': {'read_only': True},
    #         'is_ground_name': {'read_only': True},
    #         'ground_num_shu': {'read_only': True},
    #     }

    # # 跨表取数据
    # ground_num_shu = serializers.SerializerMethodField(read_only=True)

    # 必须配合一个方法get_字段名
    # 查看已经上架的药物数量
    # def get_ground_num_shu(self, obj):
    #     if obj.is_ground:
    #         return obj.total
    #     else:
    #         return 0

    # is_ground_name = serializers.SerializerMethodField(read_only=True)
    # 药品是否上架
    # def get_is_ground_name(self, obj):
    #     if obj.is_ground:
    #         return '已上架'
    #     else:
    #         return '未上架'

    # department_name = serializers.SerializerMethodField(read_only=True)
    # 关联的科室表查询
    # def get_department_name(self, obj):
    #     department_name_list = []
    #     department_list = []
    #     for department in obj.department.all():
    #         department_list.append({'name': department.name})
    #     for dep in department_list:
    #         department_name_list.append(dep.get('name'))
    #     return department_name_list

# 对药品管理表序列化类
class MedicineSerializers(serializers.ModelSerializer):
    class Meta:
        model = Medicine
        # 添加要序列化的字段
        fields = ['id', 'name', 'med_number', 'category', 'total', 'is_ground', 'price', 'department',
                  'department_name', 'is_ground_name', 'ground_num', 'ground_num_shu']
        extra_kwargs = {
            # 'department': {'read_only': True},
            'department_name': {'read_only': True},
            'is_ground_name': {'read_only': True},
            'ground_num_shu': {'read_only': True},
        }

    # # 跨表取数据
    ground_num_shu = serializers.SerializerMethodField(read_only=True)

    # 必须配合一个方法get_字段名
    # 查看已经上架的药物数量
    def get_ground_num_shu(self, obj):
        if obj.is_ground:
            return obj.total
        else:
            return 0

    is_ground_name = serializers.SerializerMethodField(read_only=True)
    # 药品是否上架
    def get_is_ground_name(self, obj):
        if obj.is_ground:
            return '已上架'
        else:
            return '未上架'

    department_name = serializers.SerializerMethodField(read_only=True)
    # 关联的科室表查询
    def get_department_name(self, obj):
        department_name_list = []
        department_list = []
        for department in obj.department.all():
            department_list.append({'name': department.name})
        for dep in department_list:
            department_name_list.append(dep.get('name'))
        return department_name_list

# 序列化科室表的名称和id
class DepartmentSerializersss(serializers.ModelSerializer):
    class Meta:
        model = Department
        fields = ['id', 'name']


# 对科室表序列化类
############################获取科室信息#############################
class DepartmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Department
        fields = [
            'id', 'name', 'department_code', 'add_name', 'add_time', 'depart_type', 'depart_type_name',
            'doctor_type'
        ]
        extra_kwargs = {
            'depart_type': {'write_only': True},
            'add_time': {'read_only': True},
            'doctor_type': {'read_only': True},
        }
    depart_type_name = serializers.SerializerMethodField(read_only=True)

    def get_depart_type_name(self, obj):
        return obj.get_depart_type_display()

# 药房开单的序列化
class GetMedicineSerializer(serializers.ModelSerializer):
    class Meta:
        model = Medicine
        fields = ['id', 'name', 'total', 'price', 'is_ground']

class GetUserSerializer(serializers.ModelSerializer):
    department = DepartmentSerializer()
    class Meta:
        # {obj1,obj2}
        # [{},{},{}]
        model = Doctor
        fields = ['name', 'mobile', 'gender_name', 'data_birth', 'department', 'job', 'assess']
        extra_kwargs = {
            'job': {'read_only': True}
        }

    gender_name = serializers.SerializerMethodField(read_only=True)

    def get_gender_name(self, obj):
        return obj.get_gender_display()



class UpdatePasswordSerializer(serializers.ModelSerializer):
    user = serializers.CharField()

    password = serializers.CharField()
    old_pwd = serializers.CharField()
    confirm_pwd = serializers.CharField()

    class Meta:
        model = User
        fields = ['username', 'password', 'old_pwd', 'confirm_pwd']


    def validate(self, attrs):
        print(attrs,'>>>>>')
        username = attrs.get('username')
        old_password = attrs.get('old_pwd')
        print(type(username),old_password)
        ret = make_password(old_password)
        print(ret)
        # user = authenticate(username=username)
        # print(user,'>>>>')
        user = User.objects.all().get(username=username)

        if not user:
            raise APIException('用户不存在！！！')
        ret = check_password(old_password,user.password)
        if not ret:
            raise APIException('旧密码输入不正确！！')
        # print(ret,'>>>>>>>>')
        password = attrs.get('password')
        confirm_pwd = attrs.get('confirm_pwd')
        if not password == confirm_pwd:
            raise APIException('两次密码不一致！！！')
        # user.set_password(password)
        # user.save()

        return attrs


# class MedicineSer(serializers.ModelSerializer):
#     class Meta:
#         model = Medicine
#         fields = ['id', 'name', 'category']
#
#     depart_type_name = serializers.SerializerMethodField(read_only=True)


class MedicineSer(serializers.ModelSerializer):
    class Meta:
        model = Medicine
        fields = ['id', 'name', 'category']


# 序列化科室表的名称和id
class DepartmentSerializerss(serializers.ModelSerializer):
    class Meta:
        model = Department
        fields = ['id', 'name']